package com.hqq.util;

import com.hqq.helper.DBHelper;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * DBUtil
 * 数据操作工具类
 * Created by heqianqian on 2017/7/22.
 */
public class DBUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(DBUtil.class);

    private static QueryRunner QUERY_RUNNER = new QueryRunner();


    /**
     * 执行查询语句
     *
     * @param sql    Sql语句
     * @param params 参数
     * @return List<Map<String,Object>>
     */
    public static List<Map<String, Object>> executeQuery(String sql, Object... params) {
        List<Map<String, Object>> result = new ArrayList<>();
        try {
            Connection connection = DBHelper.getConnection();
            result = QUERY_RUNNER.query(connection, sql, new MapListHandler(), params);
        } catch (Exception e) {
            LOGGER.error("execute update failure", e);
            throw new RuntimeException(e);
        } finally {
            DBHelper.closeConnection();
        }
        return result;
    }

    /**
     * 执行更新语句
     *
     * @param sql    sql
     * @param params 参数
     * @return 更新记录条数
     */
    private static int executeUpdate(String sql, Object... params) {
        int rows = 0;
        try {
            Connection connection = DBHelper.getConnection();
            rows = QUERY_RUNNER.update(connection, sql, params);
        } catch (Exception e) {
            LOGGER.error("execute update error!");
            throw new RuntimeException(e);
        } finally {
            DBHelper.closeConnection();
        }
        return rows;
    }

    /**
     * 查询实体类列表
     *
     * @param entityClass 实体类名
     * @param sql         sql语句
     * @param params      sql参数
     * @param <T>         实体类型
     * @return List<T>
     */
    public static <T> List<T> queryEntityList(Class<T> entityClass, String sql, Object... params) {
        List<T> entityList = new ArrayList<>();
        try {
            entityList = QUERY_RUNNER.query(DBHelper.getConnection(), sql, new BeanListHandler<T>(entityClass), params);
        } catch (SQLException e) {
            LOGGER.error("execute query failure", e);
            throw new RuntimeException(e);
        } finally {
            DBHelper.closeConnection();
        }
        return entityList;
    }

    /**
     * 插入实体类
     *
     * @param entityClass 实体类名
     * @param fieldMap    字段以及值的映射
     * @param <T>         T 实体类类型
     * @return 是否删除成功
     */
    public static <T> boolean insertEntity(Class<?> entityClass, Map<String, Object> fieldMap) {
        if (CollectionUtil.isEmpty(fieldMap)) {
            //没有参数
            LOGGER.error("can not insert entity:field map is empty");
            return false;
        }
        String sql = "INSERT INTO " + getTableName(entityClass);
        //拼接插入语句
        StringBuilder columns = new StringBuilder("(");
        StringBuilder values = new StringBuilder("(");
        //列名
        for (String fieldName : fieldMap.keySet()) {
            columns.append(fieldName).append(",");
            values.append("?, ");
        }
        columns.replace(columns.lastIndexOf(","), columns.length(), ")");
        values.replace(values.lastIndexOf(","), values.length(), ")");
        sql += columns + " VALUES" + values;

        //参数
        Object[] params = fieldMap.values().toArray();
        return executeUpdate(sql, params) == 1;
    }


    /**
     * 更新实体
     *
     * @param entityClass 实体类名
     * @param id          id
     * @param fieldMap    参数和值
     * @param <T>         返回实体类类型
     * @return 是否删除成功
     */
    public static <T> boolean updateEntity(Class<?> entityClass, Long id, Map<String, Object> fieldMap) {
        if (CollectionUtil.isEmpty(fieldMap)) {
            //没有参数
            LOGGER.error("can not update entity:field map is empty");
            return false;
        }

        String sql = "UPDATE " + getTableName(entityClass) + " SET ";
        StringBuilder columns = new StringBuilder();
        for (String fieldName : fieldMap.keySet()) {
            columns.append(fieldName).append("=?, ");
        }
        sql += columns.substring(0, columns.lastIndexOf(",")) + " WHERE id=?";

        List<Object> paramList = new ArrayList<>();
        paramList.addAll(fieldMap.values());
        paramList.add(id);
        Object[] params = paramList.toArray();

        return executeUpdate(sql, params) == 1;
    }


    /**
     * 删除实体
     *
     * @param entityClass 实体类名
     * @param id          id
     * @param <T>         泛型
     * @return 是否删除成功
     */
    public static <T> boolean deleteEntity(Class<?> entityClass, Long id) {
        String sql = "DELETE FROM " + getTableName(entityClass) + " WHERE id=?";
        return executeUpdate(sql, new Object[]{id}) == 1;//TODO
    }


    /**
     * 获得表名
     *
     * @param entityClass 实体类名
     * @return 表名
     */
    private static String getTableName(Class<?> entityClass) {
        return entityClass.getSimpleName();
    }

}
